﻿using UnityEngine;
using System.Collections;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
using System.Collections.Generic;

public class ZipUtils {

	public static void CompressFile(string formPath, string toPath)
	{
		FileInfo info = new FileInfo(formPath);
		string fileName = Path.GetFileName(formPath);
		string file2 = ZipEntry.CleanName(fileName);
		ZipEntry entry = new ZipEntry(file2);
		entry.DateTime = info.LastWriteTime;
		entry.Size = info.Length;
		
		FileStream baseOutputStream = File.Create(toPath);
		ZipOutputStream zipFile = new ZipOutputStream(baseOutputStream);
		zipFile.PutNextEntry(entry);
		
		byte[] buffer = new byte[4096];
		using ( FileStream fs = File.OpenRead(formPath) ) {
			int sourceBytes;
			do {
				sourceBytes = fs.Read(buffer, 0, buffer.Length);
				zipFile.Write(buffer, 0, sourceBytes);
			} while ( sourceBytes > 0 );
		}
		
		zipFile.CloseEntry();
		zipFile.Finish ();
		zipFile.Close ();
	}

	public static void CreateZipFile(string zipName, string folderName, List<string> containNames)
	{
		FileStream fsOut = File.Create(zipName);

		ZipOutputStream zipStream = new ZipOutputStream(fsOut);

		zipStream.SetLevel(5);

		int folderOffset = folderName.Length;

		CompressFolder(folderName, zipStream, folderOffset, containNames);

		zipStream.IsStreamOwner = true;

		zipStream.Close();

		fsOut.Close();
	}

	private static void CompressFolder(string path, ZipOutputStream zipStream, int folderOffset, List<string> containNames)
	{
		string[] files = Directory.GetFiles(path);

		foreach (string fileName in files)
		{
			//Debug.LogError (fileName);
			//string filePrefix = fileName.TrimEnd(Path.GetFileName(fileName).ToCharArray());

			//filePrefix = filePrefix.Substring(0, filePrefix.Length - 1);

			//if (fileName.EndsWith(".meta") || fileName.EndsWith(".manifest") || filePrefix.EndsWith(Path.GetFileName(fileName)))

			string fileFullName = Path.GetFileName(fileName);
			if (fileName.EndsWith(".meta") || fileName.EndsWith(".manifest") || !containNames.Contains(fileFullName))
			{
				continue;
			}
			FileInfo fi = new FileInfo(fileName);

			string entryName = fileName.Substring(folderOffset);

			entryName = ZipEntry.CleanName(entryName);

			ZipEntry newEntry = new ZipEntry(entryName);
			newEntry.DateTime = fi.LastWriteTime;
			newEntry.Size = fi.Length;

			zipStream.PutNextEntry(newEntry);

			byte[] buffer = new byte[4096];

			using (FileStream streamReader = File.OpenRead(fileName))
			{
				StreamUtils.Copy(streamReader, zipStream, buffer);
			}
			zipStream.CloseEntry();
		}

		string[] folders = Directory.GetDirectories(path);

		foreach (string folder in folders)
		{
			CompressFolder(folder, zipStream, folderOffset, containNames);
		}
	}

	public static void UnZipFolder(string formPath, string toPath) {
		string[] files = Directory.GetFiles(formPath);
		for (int i=0; i<files.Length; i++) {
			string name = files[i].Replace("\\", "/");
			if (files[i].IndexOf (".meta") > 0)
				continue;
			UnZipFile (name, toPath);
		}
		string[] dirs = Directory.GetDirectories (formPath);
		for (int i=0; i<dirs.Length; i++) {
			string name = dirs[i].Replace("\\", "/");
			string toName = toPath + "/" + Path.GetFileName(name);
			if(!Directory.Exists(toName)) Directory.CreateDirectory(toName);
			UnZipFolder(name, toName);
		}
	}
	
	public static void UnZipFile(string formPath, string toPath) {
		using (ZipInputStream s = new ZipInputStream(File.OpenRead(formPath))) {
			ZipEntry theEntry;
			while ((theEntry = s.GetNextEntry()) != null) {
				string fileName = Path.GetFileName(theEntry.Name);
				if (!string.IsNullOrEmpty(fileName)) {
					string toFilePath = toPath + "/" + fileName;
					if (File.Exists(toFilePath)) {
						File.Delete(toFilePath);
					}
					using (FileStream streamWriter = File.Create(toFilePath)) {
						int size = 20480;
						byte[] data = new byte[20480];
						while (true) {
							size = s.Read(data, 0, data.Length);
							if (size > 0) {
								streamWriter.Write(data, 0, size);
							} else {
								break;
							}
						}
					}
				}
			}
		}
	}
}
